#!/usr/bin/python # for editor

import os
import sys
import tempfile

ALL_TARGET_INSTALL = 'install'

BASE_DIR        = os.path.dirname(sys._getframe().f_code.co_filename)
CONF            = os.path.join(BASE_DIR, 'scons.conf')
PREFIX          = '/usr/local'

OPTIMIZE_LV     = 2
DEBUG_CFLAGS    = '-g'
WARN_CFLAGS     = '-Wall -Wextra -Wformat=2-Wstrict-aliasing=2 -Wcast-qual -Wcast-align -Wwrite-strings -Wfloat-equal -Wpointer-arith -Wswitch-enum -Winline -finline-functions'
ANSI_CFLAGS     = '-ansi -pedantic'
CFLAGS          = '-O%d %s %s %s' % (OPTIMIZE_LV, DEBUG_CFLAGS,
        ANSI_CFLAGS, WARN_CFLAGS)

LEXFLAGS        = '-f'
YACCFLAGS       = '-d'
LD_LIB_PATH  	= 'commons'

osenv = os.environ
if sys.platform[:3] == 'win' or sys.platform == 'cygwin':
    LINKFLAGS = ' -Xlinker --enable-auto-import '
    osenv['PATH'] += ':' + LD_LIB_PATH
elif sys.platform == 'darwin':
    LINKFLAGS = ''
    if 'LD_LIBRARY_PATH' in osenv:
        osenv['LD_LIBRARY_PATH'] += ':' + LD_LIB_PATH
    else:
        osenv['LD_LIBRARY_PATH'] = LD_LIB_PATH
    if 'DYLD_LIBRARY_PATH' in osenv:
        osenv['DYLD_LIBRARY_PATH'] += ':' + LD_LIB_PATH
    else:
        osenv['DYLD_LIBRARY_PATH'] = LD_LIB_PATH
else:
    LINKFLAGS = ''
    if 'LD_LIBRARY_PATH' in osenv:
        osenv['LD_LIBRARY_PATH'] += ':' + LD_LIB_PATH
    else:
        osenv['LD_LIBRARY_PATH'] = LD_LIB_PATH

# options
opts = Options(CONF, ARGUMENTS)
opts.Add(PathOption('PREFIX',
                    'install architecture-independent files in PREFIX',
                    PREFIX))
opts.Add(PathOption('EPREFIX',
                    'install architecture-dependent files in EPREFIX',
                    PREFIX))
opts.Add('LIBPREFIX',
         'prepend LIBPREFIX to installed static library names')
opts.Add('LIBSUFFIX',
         'append LIBSUFFIX to installed static library names')
opts.Add('SHLIBPREFIX',
         'prepend LIBPREFIX to installed shared library names')
opts.Add('SHLIBSUFFIX',
         'append LIBSUFFIX to installed shared library names')
opts.Add(BoolOption('STATIC', 'build static libraries', False))
opts.Add(BoolOption('PROFILE', 'build runtime libraries for profiling', True))

# environment
prefix      = '$PREFIX'
eprefix     = '$EPREFIX'
inc_dir     = '$PREFIX/include'
lib_dir     = '$EPREFIX/lib'
bin_dir     = '$EPREFIX/bin'
data_dir    = '$EPREFIX/share'

def lg_builder():
    def modify_target(target, source, env):
        return target, source

    return Builder(action='$LINEGUIDE $SOURCE',
                   suffix='.c',
                   src_suffix='.lg',
                   emitter=modify_target)

def objc_static_object_builder():
    def modify_target(target, source, env):
        return target, source

    return Builder(action='$OBJC -o $TARGET -c $_CPPINCFLAGS $OBJCFLAGS $SOURCE',
                   suffix='.o',
                   src_suffix='.m',
                   emitter=modify_target)

def objc_shared_object_builder():
    def modify_target(target, source, env):
        for t in target:
            t.attributes.shared = 1
        return target, source

    return Builder(action='$OBJC -o $TARGET -c -fPIC $_CPPINCFLAGS $OBJCFLAGS $SOURCE',
                   suffix='.os',
                   src_suffix='.m',
                   emitter=modify_target)

env = Environment(options=opts,
                  ENV=osenv,
                  BINDIR=bin_dir,
                  INCDIR=inc_dir,
                  LIBDIR=lib_dir,
                  CPPPATH=[inc_dir],
                  LIBPATH=[lib_dir],
                  CFLAGS=CFLAGS,
                  LEXFLAGS=LEXFLAGS,
                  YACCFLAGS=YACCFLAGS,
                  BUILDERS={'Lineguide':lg_builder(),
                      'ObjCObject':objc_static_object_builder(),
                      'ObjCSharedObject':objc_shared_object_builder()})
env['LINKFLAGS']+= LINKFLAGS
opts.Update(env)
if os.path.exists(CONF):
    path = CONF + '.temp'
    opts.Save(path, env)
    if os.path.exists(CONF) and file(CONF).read() != file(path).read():
        os.rename(path, CONF)
    else:
        os.unlink(path)
else:
    opts.Save(CONF, env)

Help(opts.GenerateHelpText(env))
env.Alias('install', bin_dir)
env.Alias('install', inc_dir)
env.Alias('install', lib_dir)
env.Clean('config.log', 'config.log')

def is_targeted(*targets):
    if not COMMAND_LINE_TARGETS:
        return True
    elif ALL_TARGET_INSTALL in COMMAND_LINE_TARGETS:
        return True
    else:
        for target in targets:
            if target in COMMAND_LINE_TARGETS:
                return True
        return False

env.is_targeted = is_targeted
env.SConscript(['commons/SConscript',
                'compiler/SConscript',
                'runtime/SConscript'],
               exports='WARN_CFLAGS CONF env prefix eprefix inc_dir lib_dir bin_dir data_dir')

